18.1 入门项目
说明:
18.2 KVC简介
说明:通过
键/值编码(KVC),没有相应getter方法也能获取属性值,没有相应setter方法也能设置属性值。
自动开箱和装箱:仅KVC具有这种功能,常规方法调用和属性语法不具备该功能。
valueForKey实例方法
说明:将属性名作为
键获取属性的值。
原理:在Objective-C的运行中使用元数据打开对象并进入其中查找需要的信息,查找顺序为
- 以参数命名(
key或isKey)的getter- 名称为
_key或key的实例变量自动装箱:通过该方法获取属性值时,如果属性为
标量(int、float、struct),该方法会根据需要将属性放入NSNumber或NSValue中。
兼容性:在C或C++中不能执行这种操作。
原型:NSKeyValueCoding.h
1 | /** |
setValue:forkey实例方法
说明:将属性名作为
键设置属性的值。
自动开箱:使用该方法设置属性时,如果属性是标量(int、float、struct),则会从新值(id)中提取出和属性类型相符的标量。
技巧:如果想设置一个标量值,在调用setValue方法之前需要将它们包装掐来(封装到对象中)。
原型:NSKeyValueCoding.h
1 | /** |
1 | // 创建 Car 对象 |
18.3 键路径
说明:进行
get和set操作,除了通过键,还可以通过键路径。键路径可以根据对象图访问到任意深度的对象,比使用一系列嵌套方法调用更容易访问到对象。
valueForKeyPath实例方法
说明:将属性名作为
键获取属性的值。
原型:NSKeyValueCoding.h
1 | /** |
setValue:forKeyPath实例方法
说明:将属性名作为
键设置属性的值。
原型:NSKeyValueCoding.h
1 | /** |
1 | // 通过 KVC 设置车的引擎的马力 |
18.4 整体操作
说明:如果使用
键值或键路径访问位于对象中的数组类型的实例属性的元素,实际上会对数组中所有元素进行操作。如果是查询操作,则还会将查询结果打包到另一个数组中并返回。
注意:这种整体操作意味着无法在键路径中单独索引数组类型的属性的其中一个元素。
1 | // 通过 KVC 访问车的轮胎的胎压,会便利tires的每个属性,并将所有tires的属性的pressure变量封装到 NSNumber 对象中并返回 |
18.4.1 休息一下
说明:创建一个新的类用于后面的学习使用。
Garage.h
1 |
|
Garage.m
1 |
|
main.m
1 | // 汽车集合 |
18.4.2 快速运算
说明:
键路径中可以使用进行引用一些运算符进行一些运算,比如
- prevProperty.
@count:计算 prevProperty 包含的对象的总数- prevProperty.
@sum.nextProperty:计算prevProperty包含的所有对象的nextProperty属性的总和- prevProperty.
@avg.nextProperty:计算prevProperty包含的所有对象的nextProperty属性的平均值- prevProperty.
@max.nextProperty:计算prevProperty包含的所有对象的nextProperty属性的最大值- prevProperty.
@min.nextProperty:计算prevProperty包含的所有对象的nextProperty属性的最小值- prevProperty.
@distinctUnionOfObjects.nextProperty:获得从prevProperty包含的所有对象的nextProperty属性构成的集合去重后的集合注意:不要滥用
KVC通过键路径提供的处理集合类的快速运算特性,因为
- 速度比较慢
- 编译器无法对它进行错误检查(出现运行时错误时才能发觉)
限制:无法添加自定义的运算符
1 | // @count |
18.5 批处理
说明:
KVC提供了对对象进行批量操作的方式。
setValuesForKeysWithDictionary实例方法
说明:通过
字典对对象进行批量set。
原型:NSKeyValueCoding.h
1 | /** |
dictionaryWithValuesForKeys实例方法
说明:通过
数组对对象进行批量set
原型:NSKeyValueCoding.h
1 | /** |
1 | // 获取汽车集合中的最后一个汽车实例 |
18.6 nil 仍然可用
背景:默认情况下,应用
KVC调用setValue:forKey设置某个属性的值为nil时,编译器会给出警告。
解决:可以通过重写setNilValueForKey方法给出有意义个返回值而避免警告。
扩展:这里的nil是标量nil,不要和[NSNull null]相混淆
1 | - (void) setNilValueForKey: (NSString *) key { |
1 | // 会将 mileage 设置为 0 |
18.7 处理未定义键
背景:如果
KVC机制无法找到处理方法,会退回并询问该如何处理。默认的实现会取消操作。
解决:通过重写setValue:forUndefinedKey和valueForUndefinedKey更改默认行为,使对象可以设置和获取任何键。
1 | /** |